﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Data.Objects.DataClasses;


namespace Fcdbas.Infrastructure.Querying
{
    public abstract class QueryTranslator<T>
        where T : EntityObject
    {
        public void CreateQueryAndObjectParameters(Query query,
            StringBuilder queryBuilder,
            List<ObjectParameter> parameters)
        {
            int idx = 0;
            foreach (var criterion in query.Criteria)
            {
                switch (criterion.CriteriaOperator)
                {
                    case CriteriaOperator.Equal:
                        queryBuilder.Append(
                            string.Format("it.{0}=@{1}",
                            criterion.PropertyName, criterion.PropertyName + idx .ToString()));
                        break;
                    case CriteriaOperator.LessThanOrEqual:
                        queryBuilder.Append(
                            string.Format("it.{0}<=@{1}",
                            criterion.PropertyName, criterion.PropertyName + idx.ToString()));
                        break;
                    case CriteriaOperator.MoreThanOrEqual:
                        queryBuilder.Append(
                            string.Format("it.{0}>=@{1}",
                            criterion.PropertyName, criterion.PropertyName + idx.ToString()));
                        break;
                    case CriteriaOperator.Contain:
                        queryBuilder.Append(
                            string.Format("it.{0} like %@{1}%",
                            criterion.PropertyName, criterion.PropertyName + idx.ToString()));
                        break;
                    case CriteriaOperator.IsNotNull:
                        queryBuilder.Append(
                            string.Format("it.{0} is not null",
                            criterion.PropertyName));
                        break;
                    case CriteriaOperator.IsNull:
                        queryBuilder.Append(
                            string.Format("it.{0} is null",
                            criterion.PropertyName));
                        break;
                    case CriteriaOperator.LessThan:
                        queryBuilder.Append(
                            string.Format("it.{0}<@{1}",
                            criterion.PropertyName, criterion.PropertyName + idx.ToString()));
                        break;
                    case CriteriaOperator.MoreThan:
                        queryBuilder.Append(
                            string.Format("it.{0}>@{1}",
                            criterion.PropertyName, criterion.PropertyName + idx.ToString()));
                        break;
                   
                }
                switch (criterion.QueryOperator)
                {
                    case QueryOperator.And:
                        queryBuilder.Append(" && ");
                        break;
                    case QueryOperator.Or:
                        queryBuilder.Append(" || ");
                        break;
                    case QueryOperator.None:
                        break;
                }
                if( criterion.CriteriaOperator != CriteriaOperator.IsNull && criterion.CriteriaOperator != CriteriaOperator.IsNotNull)
                    parameters.Add(new ObjectParameter(criterion.PropertyName + idx.ToString(), criterion.Value));
                idx++;
            }
        }

        public abstract ObjectQuery<T> Translate(Query query);
    }
}
